﻿using System;
using System.Web;
using Domino;
using System.Runtime.InteropServices;

namespace NotesCommonProjects
{
    /// <summary>NOTES_001：增加刷卡紀錄至出勤刷卡系統 API</summary>
    /// PPS_CODE = 員工編號。
    /// Time = 刷卡時間。
    /// Location = 刷卡門別。 

    public class NotesAddAccessDocument : IHttpHandler
    {
        //宣告Notes物件
        //總務用品申請單
        public static NotesSession session;
        public NotesDatabase db;
        public NotesView view;
        public NotesDocument temp_doc;
        public NotesDocument robot_doc;
        public NotesDocument new_doc;

        string pps_code = null;

        public void ProcessRequest(HttpContext context)
        {
            try
            {
                HttpRequest req = context.Request;

                //建立NotesSession
                session = new NotesSession();

                //Initialize方法會自動抓目前系統登入使用的Notes id檔, 並要求輸入密碼
                //session.Initialize(NotesCF.MyIdPassword);
                session.Initialize(NotesCF.AutoCCPTIdPassword); //AutoCCPT

                //檢查POST來的參數
                if (String.IsNullOrEmpty(req.Form["PPS_CODE"]) ||
                    String.IsNullOrEmpty(req.Form["Time"]) ||
                    String.IsNullOrEmpty(req.Form["Location"]))
                    throw new ArgumentException(NotesCF.ExceptionMessage_01);

                pps_code = req.Form["PPS_CODE"];
                DateTime time = ConvertTime(req.Form["Time"]);
                string location = req.Form["Location"];

                //檢查PPS_CODE
                if (!CheckPPSCode(pps_code))    //PPS_CODE為空
                    throw new ArgumentException(NotesCF.ExceptionMessage_02);

                //取得指定位置的NotesDatabase
                db = session.GetDatabase(NotesCF.TNotes01, NotesCF.InOutDatabase, false); //出勤刷卡系統

                //取得指定的NotesView
                view = db.GetView("vMIByDay");

                //取得所有文件
                temp_doc = view.GetFirstDocument();
                //first_doc_for_debug = view.GetFirstDocument();
                while (temp_doc != null)
                {
                    //找尋機器人範本文件
                    var v = temp_doc.GetItemValue("ID");
                    if (v[0] == NotesCF.SampleDocumentPpscode)
                    {
                        robot_doc = temp_doc;
                        break;
                    }
                    else
                    {
                        NotesDocument temp_doc_release = temp_doc;
                        temp_doc = view.GetNextDocument(temp_doc_release);

                        //釋放COM物件
                        NotesCF.ReleaseComObject(ref temp_doc_release);
                    }
                }

                //建立新的空白文件
                new_doc = db.CreateDocument();

                //複製範本文件所有NotesItem到新文件(值也會複製過去)
                robot_doc.CopyAllItems(new_doc, true);

                //操作Notes文件
                bool Above2 = HasAccessDocumentToday(pps_code);
                if (Above2) //檢查今日有無刷卡紀錄
                    CreateNewAccessDocuments(pps_code, time, location, true);
                else
                    CreateNewAccessDocuments(pps_code, time, location, false);

                //將文件存入Notes資料庫
                bool SaveSuccess = new_doc.Save(true, false);
                if (!SaveSuccess)
                    throw new ArgumentException(NotesCF.ExceptionMessage_04);

                //產生JsonObject
                JO.NotesAddAccessDocumentJsonObject ReturnObject = new JO.NotesAddAccessDocumentJsonObject
                {
                    chinese_name = GetChineseName2(pps_code),
                    pps_code = pps_code,
                    access_time = time.ToString(),
                    location = location,
                    above_2 = Above2
                };

                //回傳json
                context.Response.ContentType = "application/json";
                context.Response.Charset = null;
                context.Response.Write(NotesCF.Serialize(ReturnObject));
                HttpContext.Current.ApplicationInstance.CompleteRequest();

                //寫入Log
                string LogContext = "【刷卡成功】 【服務使用者：" + GetChineseName2(pps_code) + "】";
                NotesCF.WriteLog(NotesCF.AddAccessDocumentsLogDir, LogContext);
            }
            catch (ArgumentException agex)
            {
                context.Response.ContentType = "application/xml";
                context.Response.Charset = null;
                context.Response.Write(NotesCF.ExceptionXMLHeader + agex.Message + NotesCF.ExceptionXMLTail);
                HttpContext.Current.ApplicationInstance.CompleteRequest();

                //寫入Log
                if (pps_code != null)
                {
                    string LogContext = "【刷卡失敗】 【" + agex.Message + "】【服務使用者：" +
                        GetChineseName2(pps_code) + "】";
                    NotesCF.WriteLog(NotesCF.AddAccessDocumentsLogDir, LogContext);
                }
            }
            catch (Exception ex)
            {
                context.Response.ContentType = "application/xml";
                context.Response.Charset = null;
                context.Response.Write(NotesCF.ExceptionXMLHeader + ex.Message + NotesCF.ExceptionXMLTail);
                HttpContext.Current.ApplicationInstance.CompleteRequest();

                //寫入Log
                if (pps_code != null)
                {
                    string LogContext = "【刷卡失敗】 【" + ex.Message + "】【服務使用者：" +
                        GetChineseName2(pps_code) + "】";
                    NotesCF.WriteLog(NotesCF.AddAccessDocumentsLogDir, LogContext);
                }
            }
            finally
            {
                //釋放COM物件, 倒過來釋放
                NotesCF.ReleaseComObject(ref new_doc);
                NotesCF.ReleaseComObject(ref robot_doc);
                NotesCF.ReleaseComObject(ref temp_doc);
                NotesCF.ReleaseComObject(ref view);
                NotesCF.ReleaseComObject(ref db);
                NotesCF.ReleaseComObject(ref session);
            }
        }

        public DateTime ConvertTime(string time)
        {
            return Convert.ToDateTime(time);
        }

        public bool HasAccessDocumentToday(string pps_code)
        {
            //string Today = session.Evaluate("@Date(" + DateTime.Now + ")", new_doc);
            string Key = DateTime.Now.ToString("yyyyMMdd") + pps_code;

            NotesDatabase db = session.GetDatabase(NotesCF.TNotes01, NotesCF.InOutDatabase, false);
            NotesView view = db.GetView("KEYDAYID");
            NotesDocument doc = view.GetDocumentByKey(Key);

            bool ReturnValue = false;
            if (doc != null)
                ReturnValue = true;

            //釋放COM物件
            NotesCF.ReleaseComObject(ref doc);
            NotesCF.ReleaseComObject(ref view);
            NotesCF.ReleaseComObject(ref db);

            //回傳結果
            return ReturnValue;
        }
        public void CreateNewAccessDocuments(string pps_code, DateTime time, string location, bool above_2)
        {
            //new_doc.GetFirstItem("USERNAME").Values = GetFactory(pps_code);
            //new_doc.GetFirstItem("TYPE").Values = "";
            new_doc.GetFirstItem("KEY").Values = pps_code + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");

            new_doc.GetFirstItem("tFactory").Values = GetFactory(pps_code);
            new_doc.GetFirstItem("tDivision").Values = GetDivision(pps_code);
            new_doc.GetFirstItem("tCName").Values = GetChineseName2(pps_code);
            new_doc.GetFirstItem("staffnu").Values = pps_code;
            new_doc.GetFirstItem("DoorDsc").Values = location;
            new_doc.GetFirstItem("ID").Values = pps_code;
            //new_doc.GetFirstItem("Above2").Values = "";
            if (above_2)
                new_doc.AppendItemValue("Above2", "Yes");

            //new_doc.GetFirstItem("dStime").Values = session.Evaluate("@Created", new_doc);
            new_doc.GetFirstItem("dStime").Values = time;
            //new_doc.GetFirstItem("tRes").Values = "";
        }
        public string GetFactory(string pps_code)
        {
            //zClass    := "Notes" : "NoCache";
            //zDB         := @Subset(@DbName; 1) : "refe0.NSF";
            //zView     :=  "staffnu";
            //zKey       :=  staffnu ;
            //zChineseName := @Unique(@DbLookup(zClass;zDB; zView; zKey; "Unit1"));
            //@If(zKey ="";""; zChineseName)

            NotesDatabase db = session.GetDatabase(NotesCF.TNotes01, NotesCF.ReferenceDatabase, false);
            NotesView view = db.GetView("staffnu");
            NotesDocument doc = view.GetDocumentByKey(pps_code);

            string ReturnValue = null;
            if (doc == null)
                ReturnValue = "";
            else if (doc.GetItemValue("Unit1")[0] == null)
                ReturnValue = "";
            else
                ReturnValue = doc.GetItemValue("Unit1")[0];


            //釋放COM物件
            NotesCF.ReleaseComObject(ref doc);
            NotesCF.ReleaseComObject(ref view);
            NotesCF.ReleaseComObject(ref db);

            //回傳結果
            return ReturnValue;
        }
        public string GetDivision(string pps_code)
        {
            //zClass    := "Notes" : "NoCache";
            //zDB         := @Subset(@DbName; 1) : "refe0.NSF";
            //zView     :=  "staffnu";
            //zKey       :=  staffnu ;
            //zChineseName := @Unique(@DbLookup(zClass;zDB; zView; zKey; "Unit2"));
            //@If(zKey ="";""; zChineseName)

            NotesDatabase db = session.GetDatabase(NotesCF.TNotes01, NotesCF.ReferenceDatabase, false);
            NotesView view = db.GetView("staffnu");
            NotesDocument doc = view.GetDocumentByKey(pps_code);

            string ReturnValue = null;
            if (doc == null)
                ReturnValue = "";
            else if (doc.GetItemValue("Unit2")[0] == null)
                ReturnValue = "";
            else
                ReturnValue = doc.GetItemValue("Unit2")[0];

            //釋放COM物件
            NotesCF.ReleaseComObject(ref doc);
            NotesCF.ReleaseComObject(ref view);
            NotesCF.ReleaseComObject(ref db);

            //回傳結果
            return ReturnValue;
        }

        public static bool CheckPPSCode(string pps_code)
        {
            try
            {
                if (pps_code != null)
                {
                    if (GetChineseName2(pps_code) != "")
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
            catch (NullReferenceException)
            {
                return false;
            }
        }
        public static string GetChineseName2(string pps_code)
        {
            NotesDatabase db = session.GetDatabase(NotesCF.TNotes01, NotesCF.ReferenceDatabase, false);
            NotesView view = db.GetView("robot_ppscode_to_chinesename");
            NotesDocument doc = view.GetDocumentByKey(pps_code);

            string ReturnValue = null;
            if (doc == null)
                ReturnValue = "";
            else if (doc.GetItemValue("Name")[0] == null)
                ReturnValue = "";
            else
                ReturnValue = doc.GetItemValue("Name")[0];

            //釋放COM物件
            NotesCF.ReleaseComObject(ref doc);
            NotesCF.ReleaseComObject(ref view);
            NotesCF.ReleaseComObject(ref db);

            //回傳結果
            return ReturnValue;
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}